/**
 * 
 */
package com.cnhaimei.vod.net;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Random;

import android.util.Log;

import com.cnhaimei.com.VODLog;
import com.cnhaimei.net.NetSocket;
import com.cnhaimei.net.UDPSocket;
import com.cnhaimei.vod.LocalRoomsManager;
import com.cnhaimei.vod.bean.Room;
import com.cnhaimei.vod.logic.EventsManager;
import com.cnhaimei.vod.util.Util;

/**
 * 获取包厢列表<br>
 * 获取包厢IP<br>
 * 保持DC心跳<br>
 * 
 * @author jin001.wu@gmail.com <br>
 * @date 2011-7-20
 * 
 */
public class DCHeart extends UDPSocket {
	private final static String TAG = "DCHeart";
	private final static String COMM_IP = "get_room_ip,";
	private final static String COMM_RESPONSE_IP = "get_room_ip,";
	private final static String COMM_REVIEW_ROOMS = "review_list,roomname,";
	private final static String COMM_LIST_ROOMS = "list,roomname,";
	private final static String COMM_CREG = "creg,";
	private final static String ENCODING = "UTF-8";
	private final static long FRAME_MAX = 0x0FFFFFFF;
	private final static int FRAME_TIME = 1500;
	public  final static int PORT = 2033;//
	private final static String END_CHAR = ";";
	private final static String SPRIT_CHAR = ",";
	private static long frame = 0;
	private final static String DST_IP = "10.0.0.9";//"10.0.0.9";
	private final static int DST_PROT = 2003;

	private static String NET_CARD_ID = "00.e3.ac.f0.4c.01";
	
	private static String REG_DST_IP = "192.168.1.255";//"10.0.0.4";
	private final static int REG_DST_PORT = 3001;
	public final static int REG_PORT = 3100;

	public DCHeart() {
		super(PORT, 4096, 2048);
	}
	
	protected void onConnected(boolean isSuc) {
		EventsManager.G()
				.sendEvent(EventsManager.Event.CONNECTING, id, isSuc);
	}

	@Override
	protected void onReceive(DatagramPacket mPacket) {
		boolean suc = false;
		Object obj = null;
		int event = EventsManager.Event.UNDEFINE;
		try {
			String data = new String(mPacket.getData(), 0, mPacket.getLength(),
					ENCODING);
//			String data = new String(mPacket.getData(), 0, mPacket.getLength(),
//					"GB2312");
			Log.e(TAG, data);
			if (data == null || data.length() < 27) {
				return;
			}
			data = data.substring(27);
			if (data.startsWith(COMM_RESPONSE_IP)) {
				data =  data.substring(COMM_RESPONSE_IP.length());
				data = data.replace(END_CHAR, "");
				String a[] = data.split(SPRIT_CHAR);
				if (a != null && a.length > 1) {
					obj = new Room(a[0], a[1]);
					suc = true;
				}
				event = EventsManager.Event.ROOM_INFO;
			} else if (data.startsWith(COMM_LIST_ROOMS)) {
				VODLog.e(TAG, data);
				String sub = data.substring(COMM_LIST_ROOMS.length());
				if (sub.endsWith(SPRIT_CHAR)) {
					sub = sub.substring(0, sub.length() - 1);
				}
				sub = sub.replace(END_CHAR, "");
				sub = sub.trim();
				Log.e(TAG, "rooms:" + sub);
				obj = sub.split(SPRIT_CHAR);
				suc = true;
				event = EventsManager.Event.ROOMS;
			}
			else if (data.startsWith(COMM_CREG)) {
				
			}
			else {
				parseData(mPacket.getData(), mPacket.getLength());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		EventsManager.G().sendEvent(event, obj, suc);
	}
	
	public static void setRegDstIp(String strIp) {
		REG_DST_IP = strIp;
	}
	
	public static String getRegDstIp() {
		return REG_DST_IP;
	}
	
	public void parseData(byte[] head, int headLenth) {
		int flag = readInt(head, 0);
		int dataSize = readInt(head, 4);
		int dataType = readInt(head, 8);
		Log.e(TAG, "flag:" + flag);
		Log.e(TAG, "dataSize:" + dataSize);
		Log.e(TAG, "dataType:" + dataType);
		Log.e(TAG, "headLenth:" + headLenth);

		boolean suc = false;
		Object obj = null;
		int event = EventsManager.Event.UNDEFINE;
		if (flag == 1) {
			String strData = Util.readString(head, 12, ENCODING);
			int index = strData.indexOf("creg:");
			if (index >= 0) {
				strData = strData.substring("creg:".length()).trim();
			}
			
			event = EventsManager.Event.REGISTER_ROOMS;
			suc = true;
			obj = strData;
			LocalRoomsManager.G().addRoom(LocalRoomsManager.parse(strData));
			EventsManager.G().sendEvent(event, obj, suc);
		}
	}

	private byte[] writeIntByte = new byte[4];
	private ByteArrayOutputStream ByteOStream = new ByteArrayOutputStream(1024);
	public void writeInt(OutputStream os, int v) throws IOException {
		writeIntByte[0] = (byte) (v & 0xff);
		writeIntByte[1] = (byte) ((v >> 8) & 0xff);
		writeIntByte[2] = (byte) ((v >> 16) & 0xff);
		writeIntByte[3] = (byte) ((v >> 24) & 0xff);
		os.write(writeIntByte);
	}

	private void writejHead(OutputStream os, int iFlag, int size, int dataType)
			throws IOException {
		writeInt(os, iFlag);
		writeInt(os, size);
		writeInt(os, dataType);
	}

	private int readInt(byte[] b, int start) {
		int rtn = b[start + 3] & 0xff;
		rtn = (rtn << 8) + (b[start + 2] & 0xff);
		rtn = (rtn << 8) + (b[start + 1] & 0xff);
		rtn = (rtn << 8) + (b[start + 0] & 0xff);
		return rtn;
	}
	
	//请求注册
	public Boolean requestRegRooms() {
		int iFlag = DCManager.Flag; // 信息标识，暂定 0x1
		int size = 0; // data大小
		int dataType = 0; // 数据包类型：请求注册包厢
		
		String strData = "192.168.10.1,creg";
		
		try {
			byte[] strByte = strData.getBytes(ENCODING);
			size = 12 + strByte.length;
			
			final ByteArrayOutputStream byteOut = ByteOStream;
			byteOut.reset();
			writejHead(byteOut, iFlag, size, dataType);
			byteOut.write(strByte);
			//REG_DST_IP = "10.255.255.255";
			InetSocketAddress sa = new InetSocketAddress(InetAddress.getByName(REG_DST_IP), REG_DST_PORT);
			mSendPacket.setSocketAddress(sa);
			mSendPacket.setData(byteOut.toByteArray());
			mSocket.send(mSendPacket);

			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			return false;
		}
	}
	
	public void requestRoomList() {
		Log.e(TAG, "requestRoomList");
		StringBuilder request = getPreComm();
		request.append(COMM_REVIEW_ROOMS); // 请求包厢号命令
		request.append(END_CHAR);
		try {
			InetSocketAddress sa = new InetSocketAddress(InetAddress.getByName(DST_IP), DST_PROT);
			mSendPacket.setSocketAddress(sa);
			mSendPacket.setData(request.toString().getBytes(ENCODING));
			mSocket.send(mSendPacket);

		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void requestRoomIp(String room) {
		StringBuilder request = getPreComm();
		request.append(COMM_IP + room);
		request.append(",");
		request.append(END_CHAR);

		try {
			if (mSocket == null) {
				start();  // temp
			}
			InetSocketAddress sa = new InetSocketAddress(InetAddress.getByName(DST_IP), DST_PROT);
			mSendPacket.setSocketAddress(sa);
			Log.e(TAG, request.toString());
			mSendPacket.setData(request.toString().getBytes(ENCODING));
			mSocket.send(mSendPacket);

		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected StringBuilder getPreComm() {
		StringBuilder sb = new StringBuilder(50);
		sb.append(getFrame());
		sb.append(":");
		sb.append(NET_CARD_ID);
		sb.append(":");
		return sb;
	}

	protected String getFrame() {
		Long f = getUUID();
		String id = Long.toHexString(f.intValue());
//		String id = UUID.randomUUID().toString();
		String rtn = "";
		
		if (id.length() > 8) {
			id = id.substring(id.length() - 8, id.length());
		}
		for (int i = id.length() ; i < 8; i++) {
			rtn += "0";
		}
		
		rtn += id;
		Log.e(TAG, rtn);
		return rtn;
	}
	
	static Random  mRandom = new Random();

	public synchronized static long getUUID() {
//		frame++;
//		if (frame >= FRAME_MAX) {
//			frame = 0;
//		}
		
		frame = System.currentTimeMillis() % 3600000;
		frame = frame << 16;
		frame |= (mRandom.nextInt(16) << 8)  + mRandom.nextInt(16);;

		return frame;
	}

	public void start() {
		if (!isRun()) {
			new Thread(this).start();
		}
	}
	
	public static void setNetCard(String netCard) {
		if (netCard != null) {
			netCard = netCard.replace(":", ".");
			if (netCard.length() == NET_CARD_ID.length()) { // 保证字符长度以符合网络请要求
				NET_CARD_ID = netCard;
			}
		}
		Log.e(TAG, "NET_CARD_ID:" + NET_CARD_ID);
	}
}
